package cn.itcast.www.utils;

import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.HashSet;

public class GenernateUtils {

	/**
	 * 反转数组
	 * 
	 * @param array
	 *            可接受基本类型和复合类型的数组
	 * @param start
	 *            需要反转的开始位置
	 * @param end
	 *            需要反转的结束位置
	 * @return 返回一个新的反转后的数组
	 */
	public static Object common_reverse_array(Object array, int start, int end) {
		Class clazz = array.getClass();
		if (clazz.isArray()) { // 判断是否是数组
			Class elementClazz = clazz.getComponentType(); // 获取数组内元素类型
			int length = Array.getLength(array); // 获取数组长度
			Object objs = Array.newInstance(elementClazz, length); // 动态创建一个数组
			for (; start < length; ++start, --end) {
				Array.set(objs, start, Array.get(array, end - 1)); // 反转数组
			}
			return objs;
		}
		// 不是数组不处理
		return null;
	}

	/**
	 * 反转数组，该方法只能处理复合类型数组
	 * 
	 * @param array
	 *            只能接受复合类型数组
	 * @param start
	 *            需要反转的开始位置
	 * @param end
	 *            需要反转的结束位置
	 */
	public static <T> void reverse_array(T[] array, int start, int end) {
		T temp;
		for (; start < end - 1; ++start, --end) {
			temp = array[start];
			array[start] = array[end - 1];
			array[end - 1] = temp;
		}
	}

	/**
	 * 打印对象内容
	 * 
	 * @param object
	 *            可以是对象内容，包括数组和对象
	 */
	public static void common_print(Object object) {
		Class clazz = object.getClass();
		if (clazz.isArray()) { // 判断是否是数组
			int length = Array.getLength(object);
			System.out.println("[ ");
			for (int start = 0; start < length; ++start) {
				System.out.print(Array.get(object, start));
			}
			System.out.println(" ]");
		} else {
			// 不是数组
			System.out.println(object);
		}
	}

	public static <T> Object[] check_same_int(T[] array1, T[] array2) {
		HashSet<T> hs1 = new HashSet(Arrays.asList(array1));
		HashSet<T> hs2 = new HashSet(Arrays.asList(array2));
		hs1.retainAll(hs2);

		return hs1.toArray(array1);
	}

	public static <T> T[] check_same_object(T[] array1, T[] array2) {
		HashSet<T> hs = new HashSet<T>();
		HashSet<T> hs1 = new HashSet<T>(Arrays.asList(array1));
		HashSet<T> hs2 = new HashSet<T>(Arrays.asList(array2));

		for (T item : hs2) {
			if (!hs1.add(item)) {
				hs.add(item);
			}
		}
		Object[] objs = hs.toArray(); // 该方法返回原来数组的长度没变，输出的时候可能会有问题
		int length = hs.size();
		T[] arrays = (T[]) Array.newInstance(array1.getClass().getComponentType(), length);
		System.arraycopy(objs, 0, arrays, 0, length);
		return arrays;
	}

	/**
	 * 根据Type类型分类，整理了一个type -> class的转换过程，同理也包括处理Generic Type。支持多级泛型处理。
	 * 
	 * @param type
	 * @param i
	 * @return
	 */
	public static Class getClass(Type type, int i) {
		if (type instanceof ParameterizedType) { // 处理泛型类型
			return getGenericClass((ParameterizedType) type, i);
		} else if (type instanceof TypeVariable) {
			return (Class) getClass(((TypeVariable) type).getBounds()[0], 0); // 处理泛型擦拭对象
		} else {// class本身也是type，强制转型
			return (Class) type;
		}
	}
	
	private static Class getGenericClass(ParameterizedType parameterizedType, int i) {     
        Object genericClass = parameterizedType.getActualTypeArguments()[i];     
        if (genericClass instanceof ParameterizedType) { // 处理多级泛型     
            return (Class) ((ParameterizedType) genericClass).getRawType();     
        } else if (genericClass instanceof GenericArrayType) { // 处理数组泛型     
            return (Class) ((GenericArrayType) genericClass).getGenericComponentType();     
        } else if (genericClass instanceof TypeVariable) { // 处理泛型擦拭对象     
            return (Class) getClass(((TypeVariable) genericClass).getBounds()[0], 0);     
        } else {     
            return (Class) genericClass;     
        }     
    }    
}
